home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Visual Basic Source Code
/
Visual Basic Source Code.iso
/
vbsource
/
metkit
/
setup.exe
/
EXAMPLES
/
KBIND
/
KBOUND.CPP
< prev
next >
Wrap
C/C++ Source or Header
|
1997-06-08
|
5KB
|
163 lines
// Copyright (C) 1996, 1997 Meta Four Software. All rights reserved.
//
// See the comments in "kbound.h" for details on how to use this code.
//
//! rev="$Id: kbound.cpp,v 1.2 1997/05/27 00:06:43 jcw Rel $"
#include "kbound.h"
/////////////////////////////////////////////////////////////////////////////
// the default encoder does nothing
static void NullEncoder(bool encode_, int block_, char* ptr_, int len_)
{
}
void (*c4_BoundStorage::_Encoder)(bool,int,char*,int) = NullEncoder;
/////////////////////////////////////////////////////////////////////////////
#define FLAG_BYTES 2 /* Number of bytes used by copy flag. */
#define FLAG_COMPRESS 0 /* Signals that compression occurred. */
#define FLAG_COPY 1 /* Signals that a copyover occurred. */
static void fast_copy(BYTE *p_src,BYTE *p_dst,int len) /* Fast copy routine. */
{while (len--) *p_dst++=*p_src++;}
void lzrw1_decompress(BYTE *p_src_first,DWORD src_len,
BYTE *p_dst_first,DWORD *p_dst_len)
/* Input : Specify input block using p_src_first and src_len. */
/* Input : Point p_dst_first to the start of the output zone. */
/* Input : Point p_dst_len to a DWORD to receive the output length. */
/* Input : Input block and output zone must not overlap. User knows */
/* Input : upperbound on output block length from earlier compression. */
/* Input : In any case, maximum expansion possible is eight times. */
/* Output : Length of output block written to *p_dst_len. */
/* Output : Output block in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
/* Output : Writes only in Mem[p_dst_first..p_dst_first+*p_dst_len-1]. */
{WORD controlbits=0, control;
BYTE *p_src=p_src_first+FLAG_BYTES, *p_dst=p_dst_first,
*p_src_post=p_src_first+src_len;
if (*p_src_first==FLAG_COPY)
{fast_copy(p_src_first+FLAG_BYTES,p_dst_first,(int)src_len-FLAG_BYTES);
*p_dst_len=src_len-FLAG_BYTES; return;}
while (p_src!=p_src_post)
{if (controlbits==0)
{control=*p_src++; control|=(*p_src++)<<8; controlbits=16;}
if (control&1)
{WORD offset,len; BYTE *p;
offset=(*p_src&0xF0)<<4; len=1+(*p_src++&0xF);
offset+=*p_src++&0xFF; p=p_dst-offset;
while (len--) *p_dst++=*p++;}
else
*p_dst++=*p_src++;
control>>=1; controlbits--;
}
*p_dst_len=p_dst-p_dst_first;
}
/////////////////////////////////////////////////////////////////////////////
class c4_BoundReader : public CFile
{
BYTE *_begin, *_curr, *_end;
int _base;
public:
c4_BoundReader (int base_)
: _base (base_)
{
_begin = _curr = _end = new BYTE [c4_BoundStorage::kBlockSize];
}
virtual ~c4_BoundReader ()
{
delete [] _begin;
}
virtual UINT Read(void* lpBuf, UINT nCount)
{
UINT n = nCount;
while (n > 0)
{
if (_curr >= _end && !LoadNextBlock())
break;
int i = n;
if (i > _end - _curr)
i = _end - _curr;
memcpy(lpBuf, _curr, i);
lpBuf = (BYTE*) lpBuf + i;
_curr += i;
n -= i;
}
return nCount - n;
}
virtual void Write(const void* lpBuf, UINT nCount)
{
ASSERT(0);
}
private:
bool LoadNextBlock()
{
#ifdef _WIN32
HINSTANCE hInst = 0;
#else
HINSTANCE hInst = AfxGetResourceHandle();
#endif
HRSRC hRes = ::FindResource(hInst, MAKEINTRESOURCE(_base++), RT_RCDATA);
if (hRes)
{
HGLOBAL hData = ::LoadResource(hInst, hRes);
if (hData)
{
const BYTE* p = (const BYTE*) ::LockResource(hData);
DWORD k = *(const WORD*) p >> 1;
ASSERT(k <= c4_BoundStorage::kBlockSize + 2);
c4_Bytes temp;
BYTE* tempBuf = (BYTE*) memcpy(temp.SetBuffer((int) k), p, (WORD)k);
*(WORD*) tempBuf &= 1; // restore the copy flag
::UnlockResource(hData);
::FreeResource(hData);
ASSERT(c4_BoundStorage::_Encoder);
c4_BoundStorage::_Encoder(false, _base - 1,
(char*) tempBuf + 2, (int) k - 2);
lzrw1_decompress(tempBuf, k, _begin, &k);
ASSERT(k <= c4_BoundStorage::kBlockSize);
_curr = _begin;
_end = _begin + k;
return true;
}
}
return false;
}
};
/////////////////////////////////////////////////////////////////////////////
c4_BoundStorage::c4_BoundStorage (int base_)
{
c4_BoundReader reader (base_);
LoadFromStream(&reader);
}
c4_BoundStorage::~c4_BoundStorage ()
{
}
/////////////////////////////////////////////////////////////////////////////